package com.xlhl.init.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xlhl.init.mapper.PermissionMapper;
import com.xlhl.init.model.entity.Permission;
import com.xlhl.init.model.entity.RoleAssociationPermission;
import com.xlhl.init.model.vo.PermissionVO;
import com.xlhl.init.service.PermissionService;
import com.xlhl.init.service.RoleAssociationPermissionService;
import com.xlhl.init.utils.AuthUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author xlhl
 * @description 针对表【permission(权限表(二进制位控制))】的数据库操作Service实现
 * @createDate 2025-07-29 22:30:39
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission>
        implements PermissionService {

    @Resource
    private RoleAssociationPermissionService roleAssociationPermissionService;

    /**
     * 根据角色ID获取权限列表
     *
     * @param roleId 角色ID
     * @return 权限列表
     */
    @Override
    public List<PermissionVO> listByRoleId(Long roleId) {
        //  根据角色ID 获取角色关联表中的 权限主项与权限位图
        List<RoleAssociationPermission> roleAssociationPermissions = roleAssociationPermissionService.lambdaQuery()
                .select(RoleAssociationPermission::getRoleId, RoleAssociationPermission::getPermissionMainId, RoleAssociationPermission::getPermission)
                .eq(RoleAssociationPermission::getRoleId, roleId)
                .list();
        // 如果角色关联的权限列表为空，则返回空列表
        if (CollUtil.isEmpty(roleAssociationPermissions)) {
            return new ArrayList<>();
        }
        //  将 角色权限关联表中的数据 转换为一个 Map: {key: 主项ID, value: 权限信息}
        HashMap<Long, List<PermissionVO>> childrenByMainId = new HashMap<>(roleAssociationPermissions.size());

        //  保存权限位图中 1 的位置
        List<Integer> positionList = new ArrayList<>();
        //  存放主项列表
        List<PermissionVO> mainPermission = new ArrayList<>(roleAssociationPermissions.size());
        for (RoleAssociationPermission associationPermission : roleAssociationPermissions) {
            //  每次将存放 1 位置的列表情况
            positionList.clear();
            Long mainId = associationPermission.getPermissionMainId();
            Long permissions = associationPermission.getPermission();

            //  获取 主项 权限
            Permission one = this.lambdaQuery()
                    .eq(Permission::getId, mainId)
                    .one();
            mainPermission.add(this.objToVo(one));

            //  判断位图中拥有哪些权限（对应位数为 1 的数位）
            int longMaxLen = 64;
            for (int i = 0; i < longMaxLen; i++) {
                if (AuthUtil.checkPermission(permissions, i)) {
                    positionList.add(i);
                }
            }
            //  使用查询出的数位，查询数据库中对应主项下，对应数位的权限信息
            List<Permission> permissionList = this.lambdaQuery()
                    .eq(Permission::getFatherId, mainId)
                    .in(Permission::getBitPosition, positionList)
                    .list();
            //  将对应权限信息，添加到其主项下
            childrenByMainId.put(mainId, listToVoList(permissionList));
        }

        for (PermissionVO vo : mainPermission) {
            //  将主项对应 ID 的子项绑定
            vo.setChildren(childrenByMainId.get(vo.getId()));
        }

        return mainPermission;
    }

    /**
     * 获取全部权限列表
     *
     * @return
     */
    @Override
    public List<PermissionVO> listPermission() {
        //  获取全部权限列表
        List<PermissionVO> permissions = listToVoList(this.list());
        //  根据 fatherId 分组
        HashMap<Long, List<PermissionVO>> childrenByMainId = new HashMap<>(permissions.size());
        for (PermissionVO vo : permissions) {
            Long mainId = vo.getFatherId();
            if (!childrenByMainId.containsKey(mainId)) {
                childrenByMainId.put(mainId, new ArrayList<>());
            }
            childrenByMainId.get(mainId).add(vo);
        }
        //  将子项填充到主项下
        for (PermissionVO vo : permissions) {
            vo.setChildren(childrenByMainId.get(vo.getId()));
        }
        //  筛选出全部的 主项
        return permissions.stream().filter(v -> v.getFatherId() == -1).toList();
    }

    @Override
    public Class<PermissionVO> getVoClass() {
        return PermissionVO.class;
    }
}




